const state = {
  tcp: {
    mode: 'client',
    client: {
      host: 'localhost',
      port: 8080,
      connected: false,
      socket: null,
      encoding: 'utf8',
      lineEnding: 'none'
    },
    server: {
      port: 8080,
      listening: false,
      server: null,
      clients: [],
      encoding: 'utf8'
    }
  },
  udp: {
    mode: 'client',
    client: {
      host: 'localhost',
      port: 8081,
      localPort: null,
      socket: null,
      encoding: 'utf8'
    },
    server: {
      port: 8081,
      listening: false,
      socket: null,
      encoding: 'utf8'
    }
  },
  messages: [],
  maxMessages: 1000
}

const mutations = {
  SET_TCP_MODE(state, mode) {
    state.tcp.mode = mode
  },

  SET_UDP_MODE(state, mode) {
    state.udp.mode = mode
  },

  SET_TCP_CLIENT_CONFIG(state, config) {
    state.tcp.client = { ...state.tcp.client, ...config }
  },

  SET_TCP_SERVER_CONFIG(state, config) {
    state.tcp.server = { ...state.tcp.server, ...config }
  },

  SET_UDP_CLIENT_CONFIG(state, config) {
    state.udp.client = { ...state.udp.client, ...config }
  },

  SET_UDP_SERVER_CONFIG(state, config) {
    state.udp.server = { ...state.udp.server, ...config }
  },

  SET_TCP_CLIENT_CONNECTED(state, connected) {
    state.tcp.client.connected = connected
  },

  SET_TCP_SERVER_LISTENING(state, listening) {
    state.tcp.server.listening = listening
  },

  SET_UDP_CLIENT_SOCKET(state, socket) {
    state.udp.client.socket = socket
  },

  SET_UDP_SERVER_LISTENING(state, listening) {
    state.udp.server.listening = listening
  },

  ADD_TCP_CLIENT(state, client) {
    const existingIndex = state.tcp.server.clients.findIndex(c => c.id === client.id)
    if (existingIndex >= 0) {
      state.tcp.server.clients[existingIndex] = client
    } else {
      state.tcp.server.clients.push(client)
    }
  },

  REMOVE_TCP_CLIENT(state, clientId) {
    state.tcp.server.clients = state.tcp.server.clients.filter(c => c.id !== clientId)
  },

  UPDATE_TCP_CLIENT(state, { clientId, updates }) {
    const client = state.tcp.server.clients.find(c => c.id === clientId)
    if (client) {
      Object.assign(client, updates)
    }
  },

  ADD_MESSAGE(state, message) {
    state.messages.unshift({
      ...message,
      id: Date.now() + Math.random(),
      timestamp: new Date().toISOString()
    })
    
    if (state.messages.length > state.maxMessages) {
      state.messages = state.messages.slice(0, state.maxMessages)
    }
  },

  CLEAR_MESSAGES(state) {
    state.messages = []
  },

  SET_MAX_MESSAGES(state, max) {
    state.maxMessages = max
  }
}

// Import electron utils at the top of the actions
const { tcpUdp } = require('../../utils/electron')

const actions = {
  async connectTcpClient({ commit, state }) {
    try {
      const result = await tcpUdp.tcpConnect({
        host: state.tcp.client.host,
        port: state.tcp.client.port,
        encoding: state.tcp.client.encoding
      })
      
      if (result.success) {
        commit('SET_TCP_CLIENT_CONNECTED', true)
        commit('ADD_MESSAGE', {
          type: 'info',
          protocol: 'tcp',
          mode: 'client',
          direction: 'system',
          content: `Connected to ${state.tcp.client.host}:${state.tcp.client.port}`
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'tcp',
        mode: 'client',
        direction: 'system',
        content: `Connection failed: ${error.message}`
      })
      throw error
    }
  },

  async disconnectTcpClient({ commit }) {
    try {
      await tcpUdp.tcpDisconnect()
      commit('SET_TCP_CLIENT_CONNECTED', false)
      commit('ADD_MESSAGE', {
        type: 'info',
        protocol: 'tcp',
        mode: 'client',
        direction: 'system',
        content: 'Disconnected from server'
      })
    } catch (error) {
      console.error('TCP disconnect error:', error)
    }
  },

  async sendTcpMessage({ commit, state }, { message, target }) {
    try {
      const protocol = state.tcp.mode === 'client' ? 'tcp' : 'tcp-server'
      const result = await tcpUdp.tcpSend({
        protocol,
        message,
        target,
        encoding: state.tcp[state.tcp.mode].encoding,
        lineEnding: state.tcp.client.lineEnding
      })
      
      if (result.success) {
        commit('ADD_MESSAGE', {
          type: 'sent',
          protocol: 'tcp',
          mode: state.tcp.mode,
          direction: 'out',
          content: message,
          target
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'tcp',
        mode: state.tcp.mode,
        direction: 'system',
        content: `Send failed: ${error.message}`
      })
      throw error
    }
  },

  async startTcpServer({ commit, state }) {
    try {
      const result = await tcpUdp.tcpStartServer({
        port: state.tcp.server.port,
        encoding: state.tcp.server.encoding
      })
      
      if (result.success) {
        commit('SET_TCP_SERVER_LISTENING', true)
        commit('ADD_MESSAGE', {
          type: 'info',
          protocol: 'tcp',
          mode: 'server',
          direction: 'system',
          content: `TCP server listening on port ${state.tcp.server.port}`
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'tcp',
        mode: 'server',
        direction: 'system',
        content: `Failed to start server: ${error.message}`
      })
      throw error
    }
  },

  async stopTcpServer({ commit }) {
    try {
      await tcpUdp.tcpStopServer()
      commit('SET_TCP_SERVER_LISTENING', false)
      commit('ADD_MESSAGE', {
        type: 'info',
        protocol: 'tcp',
        mode: 'server',
        direction: 'system',
        content: 'TCP server stopped'
      })
    } catch (error) {
      console.error('TCP server stop error:', error)
    }
  },

  async startUdpClient({ commit, state }) {
    try {
      const result = await tcpUdp.udpBind({
        mode: 'client',
        localPort: state.udp.client.localPort,
        encoding: state.udp.client.encoding
      })
      
      if (result.success) {
        commit('SET_UDP_CLIENT_SOCKET', true)
        commit('ADD_MESSAGE', {
          type: 'info',
          protocol: 'udp',
          mode: 'client',
          direction: 'system',
          content: `UDP client ready${state.udp.client.localPort ? ` on port ${state.udp.client.localPort}` : ''}`
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'udp',
        mode: 'client',
        direction: 'system',
        content: `Failed to start UDP client: ${error.message}`
      })
      throw error
    }
  },

  async stopUdpClient({ commit }) {
    try {
      await tcpUdp.udpClose('client')
      commit('SET_UDP_CLIENT_SOCKET', false)
      commit('ADD_MESSAGE', {
        type: 'info',
        protocol: 'udp',
        mode: 'client',
        direction: 'system',
        content: 'UDP client stopped'
      })
    } catch (error) {
      console.error('UDP client stop error:', error)
    }
  },

  async sendUdpMessage({ commit, state }, message) {
    try {
      const result = await tcpUdp.udpSend({
        mode: state.udp.mode,
        host: state.udp.client.host,
        port: state.udp.client.port,
        message,
        encoding: state.udp[state.udp.mode].encoding
      })
      
      if (result.success) {
        commit('ADD_MESSAGE', {
          type: 'sent',
          protocol: 'udp',
          mode: state.udp.mode,
          direction: 'out',
          content: message,
          target: `${state.udp.client.host}:${state.udp.client.port}`
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'udp',
        mode: state.udp.mode,
        direction: 'system',
        content: `Send failed: ${error.message}`
      })
      throw error
    }
  },

  async startUdpServer({ commit, state }) {
    try {
      const result = await tcpUdp.udpBind({
        mode: 'server',
        port: state.udp.server.port,
        encoding: state.udp.server.encoding
      })
      
      if (result.success) {
        commit('SET_UDP_SERVER_LISTENING', true)
        commit('ADD_MESSAGE', {
          type: 'info',
          protocol: 'udp',
          mode: 'server',
          direction: 'system',
          content: `UDP server listening on port ${state.udp.server.port}`
        })
      }
      
      return result
    } catch (error) {
      commit('ADD_MESSAGE', {
        type: 'error',
        protocol: 'udp',
        mode: 'server',
        direction: 'system',
        content: `Failed to start server: ${error.message}`
      })
      throw error
    }
  },

  async stopUdpServer({ commit }) {
    try {
      await tcpUdp.udpClose('server')
      commit('SET_UDP_SERVER_LISTENING', false)
      commit('ADD_MESSAGE', {
        type: 'info',
        protocol: 'udp',
        mode: 'server',
        direction: 'system',
        content: 'UDP server stopped'
      })
    } catch (error) {
      console.error('UDP server stop error:', error)
    }
  },

  handleIncomingMessage({ commit }, { protocol, mode, message, source }) {
    commit('ADD_MESSAGE', {
      type: 'received',
      protocol,
      mode,
      direction: 'in',
      content: message,
      source
    })
  },

  handleTcpClientConnect({ commit }, client) {
    commit('ADD_TCP_CLIENT', client)
    commit('ADD_MESSAGE', {
      type: 'info',
      protocol: 'tcp',
      mode: 'server',
      direction: 'system',
      content: `Client connected: ${client.address}:${client.port}`
    })
  },

  handleTcpClientDisconnect({ commit }, clientId) {
    const client = state.tcp.server.clients.find(c => c.id === clientId)
    if (client) {
      commit('ADD_MESSAGE', {
        type: 'info',
        protocol: 'tcp',
        mode: 'server',
        direction: 'system',
        content: `Client disconnected: ${client.address}:${client.port}`
      })
    }
    commit('REMOVE_TCP_CLIENT', clientId)
  }
}

const getters = {
  tcpMode: state => state.tcp.mode,
  udpMode: state => state.udp.mode,
  tcpClientConfig: state => state.tcp.client,
  tcpServerConfig: state => state.tcp.server,
  udpClientConfig: state => state.udp.client,
  udpServerConfig: state => state.udp.server,
  tcpConnected: state => state.tcp.client.connected,
  tcpListening: state => state.tcp.server.listening,
  udpClientActive: state => !!state.udp.client.socket,
  udpListening: state => state.udp.server.listening,
  tcpClients: state => state.tcp.server.clients,
  messages: state => state.messages,
  filteredMessages: state => (filter) => {
    if (!filter) return state.messages
    return state.messages.filter(msg => {
      if (filter.protocol && msg.protocol !== filter.protocol) return false
      if (filter.mode && msg.mode !== filter.mode) return false
      if (filter.type && msg.type !== filter.type) return false
      return true
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}